package keter.ssh;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;

import keter.framework.AbstractBaseSSHConfig;
import keter.ssh.cli.Parser;
import keter.ssh.core.SshUtil;
import keter.ssh.exec.Executor;
import keter.ssh.hosts.Assembler;
import keter.ssh.hosts.Fetcher;
import keter.ssh.hosts.SimpleFetcher;

public class SshBatchMain extends AbstractBaseSSHConfig{

	/**
	 * Logger for this class
	 */
	private static final Logger logger = LoggerFactory.getLogger(SshBatchMain.class);
	
	private static String args[];
	
	public static Fetcher getFetcher(){
		return new SimpleFetcher();
	}
	
	public static void fire(String args[]) throws Exception{
		fire("hosts.properties",args);
	}
	
	/**
	 * 功能描述
	 * @param configUrl
	 * @param args
	 * @throws Exception 
	 * @author gulixing@msn.com
	 * @date   2016年7月27日
	 */
	public static void fire(String configUrl, String args[]) throws Exception{
		useConfig(configUrl);
		SshBatchMain.args = args;
		//初始化多线程执行机
		Executor.initThread(prop.getInt("thread"));
		
		//命令转换
		if(args[0].equals("get")){
			args[0] = "-g";
		}
		if(args[0].equals("put")){
			args[0] = "-p";
		}
		
		//解析初始化
		Parser.init(args); 
		
		//将主机清单装配成多线程的SshUtil对象
		List<ListenableFuture<SshUtil>> futures = Assembler.assemb(
				getFetcher().getHosts(SshBatchMain.prop),
				prop.getInt("thread"),
				prop.getInt("timeout")
		);
		
		//卍解！！
		performFutures(futures);
	}

	private static void performFutures(List<ListenableFuture<SshUtil>> futures) {
		//顺序返回结果，空值或错误使用null替代
		ListenableFuture<List<SshUtil>> successfulQueries = Futures.successfulAsList(futures);
		Futures.addCallback(successfulQueries, new FutureCallback<List<SshUtil>>() {
			//只在futures执行完成时被调用一次  
			@Override
			  public void onSuccess(List<SshUtil> results) {
//			      if(successfulQueries.isDone()){
			    	try {
			    		//统计失败数
			    		int failure = sumFailures(results);
			    		logger.info("[OK]主机全部初始化完成，成功:{}，失败:{}",results.size()-failure,failure);
				    	Parser.praseAndExec(results);
					} catch (InterruptedException e) {
						logger.error("命令执行失败",e);
					}
//			      }
			  }

			private int sumFailures(List<SshUtil> results) {
				int failure=0;
				for (int i = 0; i < results.size(); i++) {
					if(results.get(i)==null){
						failure++;
					}
				}
				return failure;
			}

			  @Override
			  public void onFailure(Throwable t) {
			      logger.error("执行失败",t);
			  }
	    });
	}
	
	public static void main(String[] args) throws Exception{
		fire(args);
	}
}
